package com.haixiaoke.saas.role.service.impl;

import java.util.*;

import cn.hutool.core.util.ObjectUtil;
import com.haixiaoke.saas.common.annotation.DataScope;
import com.haixiaoke.saas.common.constant.UserConstants;
import com.haixiaoke.saas.common.core.domain.entity.SysMenu;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.utils.StringUtils;
import com.haixiaoke.saas.department.service.IBizTenantMenuService;
import com.haixiaoke.saas.role.domain.BizRole;
import com.haixiaoke.saas.role.domain.BizRoleDept;
import com.haixiaoke.saas.role.domain.BizRoleMenu;
import com.haixiaoke.saas.role.domain.BizRolePermission;
import com.haixiaoke.saas.role.mapper.BizRoleMapper;
import com.haixiaoke.saas.role.service.IBizRoleDeptService;
import com.haixiaoke.saas.role.service.IBizRoleMenuService;
import com.haixiaoke.saas.role.service.IBizRolePermissionService;
import com.haixiaoke.saas.role.service.IBizRoleService;
import com.haixiaoke.saas.system.service.ISysMenuService;
import com.haixiaoke.saas.user.domain.BizUserRole;
import com.haixiaoke.saas.user.service.IBizUserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 企业端角色信息Service业务层处理
 *
 * @author panda
 * @date 2023-12-29
 */
@Service
public class BizRoleServiceImpl implements IBizRoleService {
    @Autowired
    private BizRoleMapper bizRoleMapper;
    @Autowired
    private IBizRoleMenuService iBizRoleMenuService;
    @Autowired
    private IBizUserRoleService iBizUserRoleService;
    @Autowired
    private IBizRoleDeptService iBizRoleDeptService;
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private IBizRolePermissionService iBizRolePermissionService;
    @Autowired
    private IBizTenantMenuService iBizTenantMenuService;

    /**
     * 查询企业端角色信息
     *
     * @param roleId 企业端角色信息主键
     * @return 企业端角色信息
     */
    @Override
    public BizRole selectBizRoleByRoleId(Long roleId) {
        return bizRoleMapper.selectBizRoleByRoleId(roleId);
    }

    /**
     * 查询企业端角色信息列表
     *
     * @param bizRole 企业端角色信息
     * @return 企业端角色信息
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<BizRole> selectBizRoleList(BizRole bizRole) {
        return bizRoleMapper.selectBizRoleList(bizRole);
    }

    /**
     * 新增企业端角色信息
     *
     * @param bizRole 企业端角色信息
     * @return 结果
     */
    @Override
    public int insertBizRole(BizRole bizRole) {
        bizRole.setCreateTime(DateUtils.getNowDate());
        bizRoleMapper.insertBizRole(bizRole);
        return insertRoleMenu(bizRole);
    }

    /**
     * 新增角色菜单信息
     *
     * @param role 角色对象
     */
    public int insertRoleMenu(BizRole role) {
        int rows = 1;
        // 新增用户与角色管理
        List<BizRoleMenu> list = new ArrayList<BizRoleMenu>();
        for (Long menuId : role.getMenuIds()) {
            BizRoleMenu rm = new BizRoleMenu();
            rm.setRoleId(role.getRoleId());
            rm.setMenuId(menuId);
            list.add(rm);
        }
        if (!list.isEmpty()) {
            rows = iBizRoleMenuService.insertBatchRoleMenu(list);
        }
        return rows;
    }

    /**
     * 修改企业端角色信息
     *
     * @param bizRole 企业端角色信息
     * @return 结果
     */
    @Override
    public int updateBizRole(BizRole bizRole) {
        bizRole.setUpdateTime(DateUtils.getNowDate());
        return bizRoleMapper.updateBizRole(bizRole);
    }

    /**
     * 批量删除企业端角色信息
     *
     * @param roleIds 需要删除的企业端角色信息主键
     * @return 结果
     */
    @Override
    public int deleteBizRoleByRoleIds(Long[] roleIds) {
        for (Long roleId : roleIds) {
            checkRoleDataScope(roleId);
            BizRole role = selectBizRoleByRoleId(roleId);
            if (iBizUserRoleService.countUserRoleByRoleId(roleId) > 0) {
                throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName()));
            }
        }
        // 删除角色与菜单关联
        iBizRoleMenuService.deleteBizRoleMenuByRoleIds(roleIds);
        // 删除角色与部门关联
        iBizRoleDeptService.deleteBizRoleDeptByRoleIds(roleIds);
        return bizRoleMapper.deleteBizRoleByRoleIds(roleIds);
    }

    /**
     * 删除企业端角色信息信息
     *
     * @param roleId 企业端角色信息主键
     * @return 结果
     */
    @Override
    public int deleteBizRoleByRoleId(Long roleId) {
        //删除角色关联数据
        iBizUserRoleService.deleteBizUserRoleByRoleId(roleId);
        iBizRoleMenuService.deleteBizRoleMenuByRoleId(roleId);
        iBizRolePermissionService.deleteBizRolePermissionByRoleId(roleId);
        iBizRoleDeptService.deleteBizRoleDeptByRoleId(roleId);
        //删除角色
        return bizRoleMapper.deleteBizRoleByRoleId(roleId);
    }

    @Override
    public void checkRoleDataScope(Long roleId) {
        BizRole role = new BizRole();
        role.setRoleId(roleId);
        List<BizRole> roles = this.selectBizRoleList(role);
        if (StringUtils.isEmpty(roles)) {
            throw new ServiceException("没有权限访问角色数据！");
        }
    }

    @Override
    public boolean checkRoleNameUnique(BizRole bizRole) {
        Long roleId = StringUtils.isNull(bizRole.getRoleId()) ? -1L : bizRole.getRoleId();
        BizRole info = bizRoleMapper.checkRoleNameUnique(bizRole.getRoleName());
        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public boolean checkRoleKeyUnique(BizRole bizRole) {
        Long roleId = StringUtils.isNull(bizRole.getRoleId()) ? -1L : bizRole.getRoleId();
        BizRole info = bizRoleMapper.checkRoleKeyUnique(bizRole.getRoleKey(),bizRole.getTenantId());
        if (ObjectUtil.isNotEmpty(info) && info.getRoleId().longValue() != roleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public Set<String> selectRolePermissionByUserIdAndTenantId(Long userId, String tenantId) {
        List<BizRole> perms = bizRoleMapper.selectRolePermissionByUserIdAndTenantId(userId, tenantId);
        Set<String> permsSet = new HashSet<>();
        for (BizRole perm : perms) {
            if (StringUtils.isNotNull(perm)) {
                permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
            }
        }
        return permsSet;
    }

    @Override
    @Transactional
    public int authDataScope(BizRole role) {
        // 修改角色信息
        bizRoleMapper.updateBizRole(role);
        // 删除角色与部门关联
        iBizRoleDeptService.deleteBizRoleDeptByRoleId(role.getRoleId());
        // 新增角色和部门信息（数据权限）
        return insertRoleDept(role);
    }

    @Override
    public int updateRoleStatus(BizRole role) {
        return bizRoleMapper.updateBizRole(role);
    }

    @Override
    public List<BizRole> selectRoleAll() {
        return this.selectBizRoleList(new BizRole());
    }

    @Override
    public int deleteAuthUser(BizUserRole userRole) {
        return iBizUserRoleService.deleteUserRoleInfo(userRole);
    }

    @Override
    public int deleteAuthUsers(Long roleId, Long[] userIds) {
        return iBizUserRoleService.deleteUserRoleInfos(roleId, userIds);
    }

    @Override
    public int insertAuthUsers(Long roleId, Long[] userIds) {
        // 新增用户与角色管理
        List<BizUserRole> list = new ArrayList<BizUserRole>();
        for (Long userId : userIds) {
            BizUserRole ur = new BizUserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
        }
        return iBizUserRoleService.batchUserRole(list);
    }

    @Override
    public int insertRole(BizRole bizRole) {
        bizRole.setCreateTime(DateUtils.getNowDate());
        return bizRoleMapper.insertBizRole(bizRole);
    }

    @Override
    public boolean checkManageRoleName(BizRole bizRole) {
        Long roleId = StringUtils.isNull(bizRole.getRoleId()) ? -1L : bizRole.getRoleId();
        BizRole info = bizRoleMapper.checkManageRoleName(bizRole.getRoleName(),bizRole.getTenantId());
        if (ObjectUtil.isNotEmpty(info) && info.getRoleId().longValue() != roleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public List<BizRole> selectRoleList(BizRole bizRole) {
        return bizRoleMapper.selectRoleList(bizRole);
    }

    @Override
    public int deleteRoleByRoleIds(Long[] roleIds) {
        // 删除角色与菜单关联
        iBizRoleMenuService.deleteBizRoleMenuByRoleIds(roleIds);
        // 删除角色与部门关联
        iBizRoleDeptService.deleteBizRoleDeptByRoleIds(roleIds);
        return bizRoleMapper.deleteBizRoleByRoleIds(roleIds);
    }

    @Override
    public List<BizRole> selectRolePage(BizRole bizRole) {
        return bizRoleMapper.selectRolePage(bizRole);
    }

    @Override
    public List<SysMenu> selectMenuList(Long roleId,String serverOwner) {
        BizRole role = bizRoleMapper.selectBizRoleByRoleId(roleId);
        List<SysMenu> menuList;
        if (StringUtils.isEmpty(role.getTenantId())) {
            SysMenu sysMenu = new SysMenu();
            sysMenu.setServerOwner(serverOwner);
            menuList = menuService.selectMenuList(sysMenu,1L);
        } else {
            menuList = iBizTenantMenuService.selectMenuByDepId(role.getTenantId());
        }
        return menuList;
    }

    @Override
    public int editMenuByRole(BizRole role) {
        //删除角色和菜单关联数据
        iBizRoleMenuService.deleteBizRoleMenuByRoleId(role.getRoleId());
        //批量插入角色和菜单关联数据
        int rows = 1;
        List<BizRoleMenu> roleMenuList = new ArrayList<>();
        for (Long menuId : role.getMenuIds()) {
            BizRoleMenu roleMenu = new BizRoleMenu();
            roleMenu.setRoleId(role.getRoleId());
            roleMenu.setMenuId(menuId);
            roleMenuList.add(roleMenu);
        }
        if (!roleMenuList.isEmpty()) {
            rows = iBizRoleMenuService.insertBatchRoleMenu(roleMenuList);
        }
        return rows;
    }

    @Override
    public List<BizRolePermission> selectPermissionByRoleId(Long roleId) {
        return iBizRolePermissionService.selectBizRolePermissionByRoleId(roleId);
    }

    @Override
    public int updateRolePermission(BizRole bizRole) {
        //删除角色与数据权限数据表
        iBizRolePermissionService.deleteBizRolePermissionByRoleId(bizRole.getRoleId());
        List<BizRolePermission> rolePermissionList = bizRole.getRolePermissionList();
        rolePermissionList.forEach(x -> x.setRoleId(bizRole.getRoleId()));
        return iBizRolePermissionService.insertBatchRolePermission(rolePermissionList);
    }

    @Override
    public boolean checkRoleExistUser(Long roleId) {
        int result = bizRoleMapper.checkRoleExistUser(roleId);
        return result > 0;
    }


    /**
     * 新增角色部门信息(数据权限)
     *
     * @param role 角色对象
     */
    public int insertRoleDept(BizRole role) {
        int rows = 1;
        // 新增角色与部门（数据权限）管理
        List<BizRoleDept> list = new ArrayList<BizRoleDept>();
        for (Long deptId : role.getDeptIds()) {
            BizRoleDept rd = new BizRoleDept();
            rd.setRoleId(role.getRoleId());
            rd.setDeptId(deptId);
            list.add(rd);
        }
        if (!list.isEmpty()) {
            rows = iBizRoleDeptService.batchRoleDept(list);
        }
        return rows;
    }
}
